﻿using CommunityToolkit.Mvvm.Input;
using ImTools;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using ZoneLinePacking.Common;
using ZoneLinePacking.Core;
using ZoneLinePacking.Core.EventArgs;
using ZoneLinePacking.Core.Extensions;
using ZoneLinePacking.Models.Entity.Template;
using ZoneLinePacking.Models.Package;
using ZoneLinePacking.Models.PrintResult;
using ZoneLinePacking.Models.StationConfig;
using ZoneLinePacking.Services.DB;
using ZoneLinePacking.Services.Message;
using ZoneLinePacking.Services.Print;
using ZoneLinePacking.ViewModelBase;
using ZoneLinePacking.Views.Dialogs;

namespace ZoneLinePacking.ViewModels {

    public class MainPackingViewModel : NavigationViewModel {

        public const string _scanBarCodeKey = "ScanBarCode";
        public const string _scanCountKey = "ScanCount";
        public const string _errorKey = "Error";
        public const string _successKey = "Success";
        public const string _messageKey = "Message";

        private readonly PrinterBoxCodeService _printerBoxService = null;
        private readonly SpeakHelper _speakerService;

        public MainPackingViewModel(
            IRegionManager regionManager, 
            IDialogService dialog, 
            IMessageService messageBox, 
            IEventAggregator eventAggregator, 
            IDbOperate<IFreeSqlMainContext> dbOperate,
            PrinterBoxCodeService printerBoxService) 
            : base(regionManager, dialog, messageBox, eventAggregator, dbOperate) {

            this._printerBoxService = printerBoxService;

            _speakerService = SpeakHelper.GetSpeakHelper();

            PackageScanConfig = _mainDbOperate.GetModel<PackageScanBarConfig>(p => true);

            ScanLinkCmd.Execute("Open");
        }

        #region Props
        private bool _isCheckOK = false;

        public bool IsCheckOK {
            get { return _isCheckOK; }
            set { _isCheckOK = value; RaisePropertyChanged(); }
        }

        private string _customer = "产品未选择";

        public string Customer {
            get { return _customer; }
            set { _customer = value; base.RaisePropertyChanged(); }
        }

        private string _model = "型号未选择";

        public string Model {
            get { return _model; }
            set { _model = value; base.RaisePropertyChanged(); }
        }

        private string _workDirection = "方向未选择";

        public string WorkDirection {
            get { return _workDirection; }
            set { _workDirection = value; base.RaisePropertyChanged(); }
        }


        private PackageScanBarConfig _packageScanConfig;

        public PackageScanBarConfig PackageScanConfig {
            get { return _packageScanConfig; }
            set => SetProperty(ref _packageScanConfig, value);
        }

        private string _portStatus = "关闭";

        public string PortStatus {
            get { return _portStatus; }
            set => SetProperty(ref _portStatus, value);
        }


        private bool _isHasUserInputParams;

        public bool IsHasUserInputParamsperty {
            get { return _isHasUserInputParams; }
            set { _isHasUserInputParams = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<ParamsEntity> _printTempUserInputParams = new ObservableCollection<ParamsEntity>();

        public ObservableCollection<ParamsEntity> PrintTempUserInputParams {
            get { return _printTempUserInputParams; }
            set { _printTempUserInputParams = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<ParamsEntity> _printTempConfigParams = new ObservableCollection<ParamsEntity>();

        public ObservableCollection<ParamsEntity> PrintTempConfigParams {
            get { return _printTempConfigParams; }
            set { _printTempConfigParams = value; base.RaisePropertyChanged(); }
        }


        private ObservableCollection<PackageTempModel> _inPackageAbsLst = new ObservableCollection<PackageTempModel>();

        public ObservableCollection<PackageTempModel> InPackageAbsLst {
            get { return _inPackageAbsLst; }
            set { _inPackageAbsLst = value; base.RaisePropertyChanged(); }
        }

        private PackageTempModel _selectInPackageAbsItem;

        public PackageTempModel SelectInPackageAbsItem {
            get { return _selectInPackageAbsItem; }
            set { _selectInPackageAbsItem = value; base.RaisePropertyChanged(); }
        }
        
        private bool _inAlarmState;
        /// <summary>
        /// 进入报警状态，需要手动确定才能继续接受扫码
        /// </summary>
        public bool InAlarmState {
            get { return _inAlarmState; }
            set { _inAlarmState = value; base.RaisePropertyChanged(); }
        }
        #endregion

        #region Commands

        public DelegateCommand SelectProductCommand => new DelegateCommand(() => {
            DialogParameters dialogParameters = new DialogParameters();
            dialogParameters.Add("Title", "装箱产品选择");
            _dialog.ShowDialog(nameof(SelectProductDialogView), dialogParameters, (rhs) => {
                IsCheckOK = rhs.Result == ButtonResult.OK;
                if (IsCheckOK) {
                    Customer = Cache.CurWorkProduct.CustomerName;
                    Model = Cache.CurWorkProduct.Model;
                    WorkDirection = Cache.CurWorkProduct.WorkDirection.GetDescription();
                    GetLastPrintTempParams();//必须在获取用户输入参数后执行
                    GetTempPackingList();//获取装箱列表数据
                }
            });
        });

        public DelegateCommand GetNewConfigInfoCmd => new DelegateCommand(() => {
            GetLastPrintTempParams();
        });


        public DelegateCommand<string> ScanLinkCmd => new DelegateCommand<string>((rhs) => {
            InitBarScanner(rhs);
        });

        public DelegateCommand CreateBoxCodePrintCmd => new DelegateCommand(() => {
            var res = _message.Ask("请确认是否需要将当前装箱列表中的产品进行【装箱】？");
            if (res != MessageBoxResult.OK) {
                return;
            }

            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), keyValuePairs, async (rhs) => {
                if (rhs.Result == ButtonResult.OK)
                {
                    await PrintBoxCode(false);
                }
            });
        });

        public DelegateCommand<string> ClearBoxCmd => new DelegateCommand<string>((args) => {
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), keyValuePairs, (rhs) => {
                if (rhs.Result == ButtonResult.OK) {
                    if (args == "CurRow") {
                        if (SelectInPackageAbsItem == null || SelectInPackageAbsItem.Code == "") {
                            return;
                        }
                        var rlt = _message.Ask("请确认是否【移除】当前所选中行?");
                        if (rlt == MessageBoxResult.OK) {
                            var res = _mainDbOperate.DeleteModel<PackageTempModel>(o => o.Code == SelectInPackageAbsItem.Code);
                            if (res) {
                                _message.GrowSuccess("清除成功！");
                                GetTempPackingList();
                            }
                        }
                    } else if (args == "AllRow") {
                        var rlt = _message.Ask("请确认是否【清除】当前箱的装箱信息，清除后需要重新扫码装箱?");
                        if (rlt == MessageBoxResult.OK) {
                            var list = _mainDbOperate.GetModelList<PackageTempModel>(o => true);
                            
                            LogManager.Warn($"清除成功，清除临时所有表数据，Count={list.Count}，PackageTempModelList：{JsonConvert.SerializeObject(list)}");
                            
                            _mainDbOperate.DeleteModel<PackageTempModel>(p => true);
                            
                            _message.GrowSuccess("清除成功！");
                            
                            GetTempPackingList();
                        }
                    }
                }
            });
            
        });

        public DelegateCommand FreshCurrentBoxCmd => new DelegateCommand(() => {
            GetTempPackingList();
            _message.GrowSuccess("刷新成功！");
        });

        public DelegateCommand ContinueBoxUpCmd => new DelegateCommand(() => {
            var curInPackageTempList = _mainDbOperate.GetModelList<PackageTempModel>(p => true);
            if (curInPackageTempList.Count > 0) {
                HandyControl.Controls.MessageBox.Error("当前列表中存在尚未装箱的产品！", "温馨提示");
                return;
            }

            bool isAuth = false;
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), keyValuePairs, (rhs) => {
                isAuth = (rhs.Result == ButtonResult.OK);
            });

            //未授权不可走后面的流程
            if (!isAuth) {
                return;
            }

            keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "继续装箱");
            _dialog.ShowDialog(nameof(ContinueBoxUpDialogView), keyValuePairs, (rhs) => {
                if (rhs.Result ==  ButtonResult.OK) {
                    GetTempPackingList();
                }
            });

        });
        #endregion

        private TemplateEntity _tempEntity;
        private List<ParamsEntity> _paramsEntities;

        protected override void OnViewLoaded() {
           
            //base.OnViewLoaded();
        }

        private async Task InsertTempBoxList(string code) {

            try {

                if (InAlarmState) {
                    return;
                }
                InAlarmState = true;

                var curInPackageTempList = _mainDbOperate.GetModelList<PackageTempModel>(p => true);
                var printConfigParams = PrintTempUserInputParams.Where(o => o.ParamsType == Enums.eParamType.Input).FirstOrDefault();
                if (printConfigParams == null) {
                    _message.Error("未查询到当前产品装箱码模板中的装箱数量配置！");
                    InAlarmState = false;
                    return;
                }

                //1.判断装箱数量是否装满，如果装满弹出提示对话框让用户确认是否打印箱码
                if (curInPackageTempList.Count.ToString() == printConfigParams.Value) {

                    var res = _message.Ask("当前装箱列表已满箱，请确认是否【装箱】并【打印】箱码？");
                    if (res == MessageBoxResult.OK) {
                        await PrintBoxCode(true);
                        InAlarmState = false;
                    }
                    return;
                }

                //2.检查该条码是否工作加工并加工完成
                var absPrintRes = _mainDbOperate.GetModel<AbsPrintResult>(p => p.Code == code);
                if (absPrintRes == null) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】装箱失败，该工件未在生产线加工或在生产线加工NG！"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                //3.检查该条码是否与当前选择的装箱产品类型是否一直
                if (absPrintRes.Brand != Cache.CurWorkProduct.CustomerName) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件【品牌】与当前选择装箱产品的【品牌不同】"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }
                if (absPrintRes.Model != null && absPrintRes.Model != Cache.CurWorkProduct.Model) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件【型号】与当前选择装箱产品的【型号不同】"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }
                if (absPrintRes.LeftRight != (int)Cache.CurWorkProduct.WorkDirection) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件【左右方向】与当前选择装箱产品的【左右方向不同】"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                //4.检查该条码是否已经在装箱中间表
                var absPackageTempRes = _mainDbOperate.GetModel<PackageTempModel>(p => p.Code == code);
                if (absPackageTempRes != null) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】装箱失败，该工件已在当前装箱列表！"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                //5.检查该条码是否已经装箱成功（！防止重码装箱！）
                var absPackageRes = _mainDbOperate.GetModel<PackageResult>(p => p.Code == code);
                if (absPackageRes != null) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】装箱失败，该工件已经被装箱！箱码：{absPackageRes.BoxCode}"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                //6.检查该条码与当前装箱列表中的产品是否相同（客户、型号、左右）
                if (curInPackageTempList.Any(o => o.Brand != absPrintRes.Brand)) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件品牌不同"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }
                if (absPrintRes.Model != null && curInPackageTempList.Any(o => o.Model != absPrintRes.Model)) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件型号不同"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }
                if (curInPackageTempList.Any(o => o.LeftRight != absPrintRes.LeftRight)) {
                    _speakerService.SpeakInfo("失败");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：产品【{code}】该工件左右方向不同"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                //7.插入临时装箱数据表中
                var pieceBoxRlt = new PackageTempModel() {
                    AbsCode = absPrintRes.AbsCode,
                    Brand = absPrintRes.Brand,
                    LeftRight = absPrintRes.LeftRight,
                    PrintTime = absPrintRes.PrintTime,
                    Code = absPrintRes.Code,
                    Model = absPrintRes.Model,
                };
                pieceBoxRlt.PackageTime = DateTime.Now;
                var recordRlt = _mainDbOperate.AddModel(pieceBoxRlt);
                if (recordRlt) {

                    GetTempPackingList();
                    var count = InPackageAbsLst.Count;
                    _speakerService.SpeakInfo($"成功");
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _successKey,$"装箱信息：装箱成功，这是该箱子的第{count}个产品"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

                    if (InPackageAbsLst.Count.ToString() == Convert.ToInt32(printConfigParams.Value).ToString())
                    {
                        //_speakerService.SpeakInfo($"当前箱产品已够数，开始自动打印！");

                        messageData = new MessageData
                        {
                            Code = nameof(MainPackingViewModel),
                            Parameters = new DialogParameters(){
                                { _successKey,$"装箱信息：当前箱产品已够数，开始自动打印！"},
                            }
                        };
                        _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

                        await PrintBoxCode(true);
                    }

                    InAlarmState = false;

                } else {
                    MessageData messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：装箱异常，记录装箱数据失败"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    _speakerService.SpeakInfo("失败");
                }

            } catch (Exception ex) {

                MessageData messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：装箱异常{ex.Message}"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                _speakerService.SpeakInfo("装箱异常");
            }

        }

        /// <summary>
        /// 打印箱码
        /// </summary>
        /// <param name="isCheckFullPackage">是否检查满箱</param>
        private async Task PrintBoxCode(bool isCheckFullPackage) {

            MessageData messageData = new MessageData();

            var curInPackageTempList = _mainDbOperate.GetModelList<PackageTempModel>(p => true);
            var printConfigParams = PrintTempUserInputParams.Where(o => o.ParamsType == Enums.eParamType.Input).FirstOrDefault();
            if (curInPackageTempList == null || curInPackageTempList.Count == 0) {
                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：打印失败，当前未进行产品录入！"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                return;
            }

            if (printConfigParams == null) {
                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：打印失败，未查询到当前产品装箱码模板中的装箱数量配置！"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                return;
            }

            var temp = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == Cache.CurWorkProduct.Id && o.TemplateType == Enums.eTemplateType.BoxCode);
            if (temp == null) {
                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：打印失败，当前产品未设置箱码打印模板！"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                return;
            }

            if (isCheckFullPackage && curInPackageTempList.Count.ToString() != Convert.ToInt32(printConfigParams.Value).ToString())
            {
                messageData = new MessageData
                {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：打印失败，当前装入产品数量与设定装箱数量不符，设定的装箱数量：{printConfigParams.Value}！"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                return;
            }

            try {

                var dic = PrintTempUserInputParams.ToDictionary(o => o.ParamsKey, o => curInPackageTempList.Count.ToString($"D{o.Length}"));
                Dictionary<string, string> printParams;
                string boxNum;
                var boxCode = _printerBoxService.GenerateQrCode(_tempEntity, dic, out boxNum, out printParams, true);
                var boxCodeExists = _mainDbOperate.CheckExist<PackageResult>(p => p.BoxCode == boxCode);
                int countExists = 0;
                while (boxCodeExists) {
                    if (countExists > 50)
                    {
                        messageData = new MessageData
                        {
                            Code = nameof(MainPackingViewModel),
                            Parameters = new DialogParameters(){
                                { _errorKey,$"装箱信息：打印失败，生成的箱码重复！"},
                            }
                        };
                        _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                        return;
                    }
                    LogManager.Info($"装箱信息：打印失败，当前信息生成的箱码是{boxCode}重复，已被装箱过，正在重新生成！");
                    boxCode = _printerBoxService.GenerateQrCode(_tempEntity, dic, out boxNum, out printParams, true);
                    boxCodeExists = _mainDbOperate.CheckExist<PackageResult>(p => p.BoxCode == boxCode);
                    LogManager.Info($"装箱信息：新生成装箱码{boxCode}，是否重复{boxCodeExists}！");
                    countExists++;
                }

                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _successKey,$"装箱信息：生成装箱码成功，箱码{boxCode}，正在打印...."},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

                var printRes = await _printerBoxService.PrintLabel(temp.TemplatePath, boxCode, printParams, PackageScanConfig.Printer);
                if (!printRes) {
                    messageData = new MessageData {
                        Code = nameof(MainPackingViewModel),
                        Parameters = new DialogParameters(){
                            { _errorKey,$"装箱信息：打印失败，请重新生成打印！"},
                        }
                    };
                    _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);
                    return;
                }

                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                            { _successKey,$"装箱信息：打印成功！"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

                var listRlt = new List<PackageResult>();
                foreach (var item in curInPackageTempList) {
                    var packageRlt = new PackageResult() {
                        AbsCode = item.AbsCode,
                        Brand = item.Brand,
                        LeftRight = item.LeftRight,
                        BoxCode = boxCode,
                        Code = item.Code,
                        PackageTime = item.PackageTime,
                        PrintTime = item.PrintTime,
                        Model = item.Model,
                    };
                    listRlt.Add(packageRlt);
                }
                var res = _mainDbOperate.AddModels(listRlt);

                if (res) {
                    //打印成功，将数据打印的数据记录到关联表中
                    var printRecord = new BoxCodePrintResult() {
                        Brand = Cache.CurWorkProduct.CustomerName,
                        Model = Cache.CurWorkProduct.Model,
                        BoxCode = boxCode,
                        LeftRight = (int)Cache.CurWorkProduct.WorkDirection,
                        PrintTime = DateTime.Now,
                        ProductID = Cache.CurWorkProduct.Id,
                        PrintParams = JsonConvert.SerializeObject(printParams),
                    };
                    _mainDbOperate.AddModel(printRecord);
                    //清除装临时箱数据
                    _mainDbOperate.DeleteModel<PackageTempModel>(p => true);
                }
                _ = App.Current.Dispatcher.InvokeAsync(() =>
                {
                    GetLastPrintTempParams();
                    GetTempPackingList();
                });

            } catch (Exception ex) {

                messageData = new MessageData {
                    Code = nameof(MainPackingViewModel),
                    Parameters = new DialogParameters(){
                        { _errorKey,$"装箱信息：打印失败，{ex.Message}"},
                    }
                };
                _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

            }
        }

        /// <summary>
        /// 获取临时装箱列表
        /// </summary>
        private void GetTempPackingList() {
            var list = _mainDbOperate.GetModelList<PackageTempModel>(p => true);
            InPackageAbsLst = new ObservableCollection<PackageTempModel>(list);
        }

        
        /// <summary>
        /// 获取最新的打印模板参数
        /// </summary>
        private void GetLastPrintTempParams() {
            var res = GetPrintTempUserInputParams();
            if (!res) return;

            PrintTempConfigParams.Clear();
            if (_tempEntity != null && PrintTempUserInputParams.Count > 0) {
                var dic = PrintTempUserInputParams.ToDictionary(o => o.ParamsKey, o => o.Value);
                Dictionary<string, string> printParams;
                string boxNum;
                var boxCode = _printerBoxService.GenerateQrCode(_tempEntity, dic, out boxNum, out printParams, false);
                if (boxCode != "" && printParams.Count > 0) {
                    foreach (var item in printParams) {
                        var keyName = _paramsEntities.FirstOrDefault(o => o.ParamsKey == item.Key)?.ParamsName;
                        var keyValue = item.Value;
                        if (keyName != null) {
                            PrintTempConfigParams.Add(new ParamsEntity { ParamsName = keyName, Value = keyValue });
                        }
                    }
                }
            } else {
                _message.Error("获取模板默认配置信息失败！");
            }
        }

        /// <summary>
        /// 获取打印模板用户输入参数信息
        /// </summary>
        private bool GetPrintTempUserInputParams() {
            if (Cache.CurWorkProduct == null) {
                return false;
            }
            _tempEntity = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == Cache.CurWorkProduct.Id && o.TemplateType == Enums.eTemplateType.BoxCode);
            if (_tempEntity != null) {
                PrintTempUserInputParams.Clear();
                _paramsEntities = _mainDbOperate.GetModelList<ParamsEntity>(o => o.TemplateID == _tempEntity.Id);
                IsHasUserInputParamsperty = _paramsEntities.Count > 0;
                if (_paramsEntities.Count > 0) {
                    PrintTempUserInputParams.AddRange(_paramsEntities.Where(o => o.ParamsType == Enums.eParamType.Input));
                }
            } else {
                _message.Error("获取模板参数信息失败！");
                return false ;
            }
            return true;
        }


        #region 扫码枪相关
        private SerialPort _scanSerial;

        private void InitBarScanner(string cmd) {
            if (cmd == "Open") {
                Task.Run(() => {
                    if (PortStatus != "打开") {
                        try {
                            PortStatus = "打开中";
                            if (_scanSerial == null) {
                                _scanSerial = new SerialPort();
                                _scanSerial.PortName = PackageScanConfig.Port;
                                _scanSerial.BaudRate = 115200;
                                _scanSerial.DataBits = 8;
                                _scanSerial.StopBits = StopBits.One;
                                _scanSerial.Parity = Parity.None;
                                _scanSerial.DataReceived += _scanSerial_DataReceived;
                            }
                            _scanSerial.Close();
                            _scanSerial.Open();
                            if (_scanSerial.IsOpen) {
                                PortStatus = "打开";
                            }
                        } catch (Exception ex) {
                            PortStatus = "打开失败，请重试！";
                        }
                        Thread.Sleep(1000);
                    }
                });
            } else {
                if (_scanSerial != null) {
                    _scanSerial?.Close();
                    if (!_scanSerial.IsOpen) PortStatus = "关闭";
                    _scanSerial?.Dispose();
                }
            }
        }

        private int count;

        private void _scanSerial_DataReceived(object sender, SerialDataReceivedEventArgs e) {
            Thread.Sleep(200);

            var lenght = _scanSerial.BytesToRead;

            var bytes = new byte[lenght];
            
            _scanSerial.Read(bytes, 0, lenght);
            
            var barCodeStr = Encoding.UTF8.GetString(bytes).Replace("\n", "").Replace("\r", "");

            count++;

            MessageData messageData = new MessageData {
                Code = nameof(MainPackingViewModel),
                Parameters = new DialogParameters(){
                    { _scanBarCodeKey, barCodeStr },
                    { _scanCountKey, count }
                }
            };
            
            _eventAggregator.GetEvent<PubSubEventArgs>().Publish(messageData);

            if (barCodeStr.Length < 30)
            { //缸体码

            }
            else if (barCodeStr.StartsWith("$"))
            {//装箱码

            }
            else
            {//标签码
                InsertTempBoxList(barCodeStr);
            }
        }
        #endregion

    }
}
